home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 1 / Precision Software Applications Silver Collection Volume One (PSM) (1993).iso / demos / devel3.exe / PCXMODEY.C < prev    next >
C/C++ Source or Header  |  1992-05-17  |  3KB  |  143 lines

  1. /* Load a PCX file in mode Y */
  2.  
  3. /* Written by Bernie Roehl, April 1992 based on code by Dave Stampe */
  4.  
  5. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  6.    May be freely used to write software for release into the public domain;
  7.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  8.    for permission to incorporate any part of this software into their
  9.    products!
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <dos.h>
  14. #include <alloc.h>
  15.  
  16. static int getbyte(int *c, int *count, FILE *in)
  17.     {
  18.     if (feof(in)) return EOF;
  19.     *c = getc(in) & 0xFF;
  20.     if ((*c & 0xC0) == 0xC0) {
  21.         *count = *c & 0x3F;
  22.         if (feof(in)) return EOF;
  23.         *c = getc(in) & 0xFF;
  24.         }
  25.     else
  26.         *count = 1;
  27.     return NULL;
  28.     }
  29.  
  30. static void putbyte(int c, int count, FILE *out)
  31.     {
  32.     if (count == 0)
  33.         return;
  34.     if (count > 1 || (c & 0xC0) == 0xC0)
  35.         putc(count | 0xC0, out);
  36.     putc(c, out);
  37.     }
  38.  
  39. static unsigned char far *screen = MK_FP(0xA000, 0);
  40.  
  41. static void write_line(char far *buffer, char far *scr)
  42. {
  43.     int i, plane;
  44.     char *add, *buff;
  45.  
  46.     for (plane = 0; plane < 4; ++plane)
  47.         {
  48.         outport(0x3C4, (1<<(plane+8))+2);
  49.         add = scr;
  50.         buff = &buffer[plane];
  51.         for (i = 0; i < 80; ++i)
  52.             {
  53.             *add++ = *buff;
  54.             buff += 4;
  55.             }
  56.         }
  57.     }
  58.  
  59. load_pcx(FILE *in, int page)
  60.     {
  61.     int c, count;
  62.     char buff[330];
  63.     char *buffer = &buff[0];
  64.     char *scr = &screen[16000*page];
  65.     unsigned nread = 0;
  66.  
  67.     reset_hdwe();
  68.     fseek(in, 128L, SEEK_SET);  /* skip PCX header */
  69.     while (getbyte(&c, &count, in) != EOF)
  70.     while (count--)
  71.         {
  72.         *buffer++ = c;
  73.         if (++nread == 320)
  74.             {
  75.             write_line(&buff[0],scr);
  76.             buffer = &buff[0];
  77.             nread = 0;
  78.             scr += 80;
  79.             }
  80.         }
  81.     return 0;
  82.     }
  83.  
  84. struct {
  85.     unsigned char manu, hard, encod, bitpx;
  86.     unsigned int x1, y1, x2, y2;
  87.     unsigned int hres, vres;
  88.     unsigned char palette[48];
  89.     unsigned char vmode, nplanes;
  90.     unsigned int bytesPerLine;
  91.     char unused[128-68];
  92.     } pccHeader = { 10, 5, 1, 8, 0, 0, 319, 199, 75, 75, { 0 }, 0x13, 1, 320, 0 };
  93.  
  94. struct { unsigned char r, g, b; } palbuff[256];
  95.  
  96. static char get_pixel(unsigned int adr, int page)
  97. {
  98.     outport(0x3CE, ((adr&3)<<8)+4);    /* select plane to read */
  99.     return *(char *)(MK_FP(0xA000+1000*page,adr>>2));
  100. }
  101.  
  102.  
  103. save_pcx(FILE *out, int page)
  104. {
  105.     unsigned c, oldc, count;
  106.     unsigned nput = 1;
  107.     union REGS r;
  108.  
  109.     reset_hdwe();
  110.     fwrite(&pccHeader, 128, 1, out);
  111.     count = 1;
  112.     oldc = get_pixel(0,page);
  113.     while ((nput>>2) < 16000)
  114.         {
  115.         c = get_pixel(nput++, page);
  116.         if (c != oldc)
  117.             {
  118.             putbyte(oldc, count, out);
  119.             oldc = c;
  120.             count = 1;
  121.             }
  122.         else if (++count >= 63)
  123.             {
  124.             putbyte(oldc, count, out);
  125.             count = 0;
  126.             }
  127.         }
  128.     putbyte(oldc, count, out);
  129.  
  130.     putc(0x0C, out);
  131.     for (count = 0; count < 256; ++count)
  132.         {
  133.         r.x.ax = 0x1015;
  134.         r.x.bx = count;                   /* write pallete */
  135.         int86(0x10, &r, &r);
  136.         putc(r.h.dh<<2, out);
  137.         putc(r.h.ch<<2, out);
  138.         putc(r.h.cl<<2, out);
  139.         }
  140.     return 0;
  141.     }
  142.  
  143.